home *** CD-ROM | disk | FTP | other *** search
/ FishMarket 1.0 / FishMarket v1.0.iso / fishies / 301-325 / disk_319 / cnewssrc / cnews.orig.lzh / rna / header.c < prev    next >
C/C++ Source or Header  |  1989-06-27  |  10KB  |  479 lines

  1. /*
  2.  * extract/output headers
  3.  */
  4.  
  5. #include "defs.h"
  6.  
  7. #if AUSAM
  8. extern struct pwent pe;
  9. #else
  10. extern struct passwd *pp;
  11. #endif
  12. extern char systemid[];
  13. extern long now;
  14.  
  15. char tzone[]         = TIMEZONE;
  16. char hform[]         = "%s: %s\n";
  17.  
  18. /* Mandatory Headers */
  19. char t_relayversion[]     = "Relay-Version";
  20. char t_postversion[]     = "Posting-Version";
  21. char t_from[]         = "From";
  22. char t_date[]         = "Date";
  23. char t_newsgroups[]     = "Newsgroups";
  24. char t_subject[]     = "Subject";
  25. char t_messageid[]     = "Message-ID";
  26. char t_path[]         = "Path";
  27.  
  28. /* Optional Headers */
  29. char t_replyto[]     = "Reply-To";
  30. char t_sender[]         = "Sender";
  31. char t_followupto[]     = "Followup-To";
  32. char t_datereceived[]     = "Date-Received";
  33. char t_expires[]     = "Expires";
  34. char t_references[]     = "References";
  35. char t_control[]     = "Control";
  36. char t_distribution[]     = "Distribution";
  37. char t_organization[]     = "Organization";
  38. char t_lines[]         = "Lines";
  39.  
  40. typedef enum ft
  41. {
  42.     f_control, f_date, f_datereceived, f_distribution,
  43.     f_expires, f_followupto, f_from, f_lines, f_messageid,
  44.     f_newsgroups, f_organization, f_path, f_postversion,
  45.     f_references, f_relayversion, f_replyto, f_sender,
  46.     f_subject
  47. }
  48.  
  49.  
  50. ftype;
  51.  
  52. typedef struct field {
  53.     char *f_name;
  54.     ftype    f_type;
  55. } field;
  56.  
  57. static field fields[] = 
  58. {
  59.     { t_control,     f_control     },
  60.     { t_date,         f_date         },
  61.     { t_datereceived,     f_datereceived     },
  62.     { t_distribution,     f_distribution     },
  63.     { t_expires,     f_expires     },
  64.     { t_followupto,     f_followupto     },
  65.     { t_from,         f_from         },
  66.     { t_lines,     f_lines         },
  67.     { t_messageid,     f_messageid     },
  68.     { t_newsgroups,     f_newsgroups     },
  69.     { t_organization,     f_organization     },
  70.     { t_path,         f_path         },
  71.     { t_postversion,     f_postversion     },
  72.     { t_references,     f_references     },
  73.     { t_relayversion,     f_relayversion     },
  74.     { t_replyto,     f_replyto     },
  75.     { t_sender,     f_sender     },
  76.     { t_subject,     f_subject     }
  77. };
  78.  
  79.  
  80. char *weekdays[7] = 
  81. {
  82.     "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"
  83. };
  84.  
  85.  
  86. char *months[12] = 
  87. {
  88.     "Jan", "Feb", "Mar", "Apr", "May", "Jun",
  89.     "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
  90. };
  91.  
  92.  
  93. static
  94. fieldcmp(a, b)
  95. field *a, *b;
  96. {
  97.     return CMP(a->f_name, b->f_name);
  98. }
  99.  
  100.  
  101. /*
  102.  * extract headers from file,
  103.  * position file to start of body
  104.  */
  105. gethead(f, hp)
  106. FILE *f;
  107. header *hp;
  108. {
  109.     register char *colon, *space, *s;
  110.     register field    *fp;
  111.     field        af;
  112.     char buf[BUFLEN*2];
  113.  
  114.     char *hfgets();
  115.  
  116.     memset((char *) hp, 0, sizeof(header));
  117.     while (hfgets(buf, sizeof(buf), f)) {
  118.         if (buf[0] == '\n')
  119.             return;
  120.         if (isupper(buf[0]) && (colon = strchr(buf, ':')) && (space =
  121.             strchr(buf, ' ')) && (colon + 1 == space)) {
  122.             *colon = '\0';
  123.             af.f_name = buf;
  124.             fp = (field * ) bsearch((char *) & af, (char *) fields,
  125.                                  sizeof(fields) / sizeof(fields[0]), sizeof(fields[0]),
  126.                  fieldcmp);
  127.             *colon = ':';
  128.         } else
  129.             fp = NIL(field);
  130.         if (!fp)
  131.             if (hp->h_others)
  132.                 hp->h_others = catstr(hp->h_others, buf);
  133.             else
  134.                 hp->h_others = newstr(buf);
  135.         else
  136.          {
  137.             if (colon = strchr(space + 1, '\n'))
  138.                 *colon = '\0';
  139.             s = newstr(space + 1);
  140.             switch (fp->f_type) {
  141.             case f_control:        
  142.                 hp->h_control = s;    
  143.                 break;
  144.             case f_date:        
  145.                 hp->h_date = s;        
  146.                 break;
  147.             case f_datereceived:    
  148.                 hp->h_datereceived = s;    
  149.                 break;
  150.             case f_distribution:    
  151.                 hp->h_distribution = s;    
  152.                 break;
  153.             case f_expires:        
  154.                 hp->h_expires = s;    
  155.                 break;
  156.             case f_followupto:    
  157.                 hp->h_followupto = s;    
  158.                 break;
  159.             case f_from:        
  160.                 hp->h_from = s;        
  161.                 break;
  162.             case f_lines:        
  163.                 hp->h_lines = s;    
  164.                 break;
  165.             case f_messageid:    
  166.                 hp->h_messageid = s;    
  167.                 break;
  168.             case f_newsgroups:    
  169.                 hp->h_newsgroups = s;    
  170.                 break;
  171.             case f_organization:    
  172.                 hp->h_organisation = s;    
  173.                 break;
  174.             case f_path:        
  175.                 hp->h_path = s;        
  176.                 break;
  177.             case f_postversion:    
  178.                 hp->h_postversion = s;    
  179.                 break;
  180.             case f_references:    
  181.                 hp->h_references = s;    
  182.                 break;
  183.             case f_relayversion:    
  184.                 hp->h_relayversion = s;    
  185.                 break;
  186.             case f_replyto:        
  187.                 hp->h_replyto = s;    
  188.                 break;
  189.             case f_sender:        
  190.                 hp->h_sender = s;    
  191.                 break;
  192.             case f_subject:        
  193.                 hp->h_subject = s;    
  194.                 break;
  195.             }
  196.         }
  197.     }
  198. }
  199.  
  200.  
  201. /*
  202.  * put headers to file
  203.  */
  204. puthead(hp, f, com)
  205. header *hp;
  206. FILE *f;
  207. pheadcom com;
  208. {
  209.     register char *s;
  210.     char *getunique();
  211.     extern char *getenv();
  212.  
  213.     if (hp->h_relayversion && com == printing)
  214.         (void) fprintf(f, hform, t_relayversion, hp->h_relayversion);
  215.     else if (com != printing)
  216.         (void) fprintf(f, "%s: version %s; site %s.%s\n", t_relayversion, NEWSVERSION
  217.  
  218.              systemid, MYDOMAIN);
  219.  
  220.     if (hp->h_postversion)
  221.         (void) fprintf(f, hform, t_postversion, hp->h_postversion);
  222.     else if (com == making)
  223.         (void) fprintf(f, "%s: version %s; site %s.%s\n", t_postversion, NEWSVERSION,
  224.              systemid, MYDOMAIN);
  225.  
  226.  
  227.     if (hp->h_from)
  228.         (void) fprintf(f, hform, t_from, hp->h_from);
  229.     else if(com == making) {
  230.         if(s = getenv("NAME"))
  231.             (void) fprintf(f, "%s: %s@%s.%s (%s)\n", t_from,
  232. #if AUSAM
  233.                 pe.pw_strings[LNAME],
  234. #else
  235.                 pp->pw_name,
  236. #endif
  237.                 systemid, MYDOMAIN, s);
  238.         else
  239.             (void) fprintf(f,
  240. #if AUSAM
  241.                 "%s: %s@%s.%s (%s %s)\n",
  242. #else
  243.                 "%s: %s@%s.%s\n",
  244. #endif
  245.                 t_from,
  246. #if AUSAM
  247.                 pe.pw_strings[LNAME],
  248. #else
  249.                 pp->pw_name,
  250. #endif
  251.                 systemid, MYDOMAIN
  252. #if AUSAM
  253.                 ,
  254.                 pe.pw_strings[FIRSTNAME],
  255.                 pe.pw_strings[LASTNAME]
  256. #endif
  257.             );
  258.     }
  259.  
  260.     if (hp->h_date)
  261.         (void) fprintf(f, hform, t_date, hp->h_date);
  262.     else if (com == making)
  263.         (void) fprintf(f, hform, t_date, ttoa(now));
  264.  
  265.     if (hp->h_newsgroups)
  266.         (void) fprintf(f, hform, t_newsgroups, hp->h_newsgroups);
  267.     else if (com == making)
  268.         (void) fprintf(f, hform, t_newsgroups, DFLTGRP);
  269.  
  270.     if (hp->h_subject)
  271.         (void) fprintf(f, hform, t_subject, hp->h_subject);
  272.     else if (com == making)
  273.         error("No subject field.");
  274.  
  275.     if (hp->h_messageid)
  276.         (void) fprintf(f, hform, t_messageid, hp->h_messageid);
  277.     else if (com == making)
  278.         error("No messageid.");
  279.  
  280.     if (hp->h_path && com == passing)
  281.         (void) fprintf(f, "%s: %s!%s\n", t_path, systemid, hp->h_path);
  282.     else if (hp->h_path)
  283.         (void) fprintf(f, hform, t_path, hp->h_path);
  284.     else if(com == making)
  285.         (void) fprintf(f, "%s: %s!%s\n", t_path, systemid,
  286. #if AUSAM
  287.             pe.pw_strings[LNAME]
  288. #else
  289.             pp->pw_name
  290. #endif
  291.         );
  292.  
  293.     /* optional */
  294.  
  295.     if (hp->h_replyto)
  296.         (void) fprintf(f, hform, t_replyto, hp->h_replyto);
  297.  
  298.     if (hp->h_sender)
  299.         (void) fprintf(f, hform, t_sender, hp->h_sender);
  300.  
  301.     if (hp->h_followupto)
  302.         (void) fprintf(f, hform, t_followupto, hp->h_followupto);
  303.  
  304.     if (hp->h_datereceived && com == printing)
  305.         (void) fprintf(f, hform, t_datereceived, hp->h_datereceived);
  306.     else if (com != printing)
  307.         (void) fprintf(f, hform, t_datereceived, ttoa(now));
  308.  
  309.     if (hp->h_expires)
  310.         (void) fprintf(f, hform, t_expires, hp->h_expires);
  311.  
  312.     if (hp->h_references)
  313.         (void) fprintf(f, hform, t_references, hp->h_references);
  314.  
  315.     if (hp->h_control)
  316.         (void) fprintf(f, hform, t_control, hp->h_control);
  317.  
  318.     if (hp->h_distribution)
  319.         (void) fprintf(f, hform, t_distribution, hp->h_distribution);
  320.  
  321.     if (hp->h_organisation)
  322.         (void) fprintf(f, hform, t_organization, hp->h_organisation);
  323.     else if (com == making)
  324.         (void) fprintf(f, hform, t_organization, (s = getenv("ORGANIZATION")) ?
  325.             s : MYORG);
  326.  
  327.     if (hp->h_lines)
  328.         (void) fprintf(f, hform, t_lines, hp->h_lines);
  329.  
  330.     if (hp->h_others)
  331.         fputs(hp->h_others, f);
  332. }
  333.  
  334.  
  335. /*
  336.  * free all strings allocated to header
  337.  */
  338. freehead(hp)
  339. register header *hp;
  340. {
  341.     if (hp->h_relayversion)    
  342.         free(hp->h_relayversion);
  343.     if (hp->h_postversion)    
  344.         free(hp->h_postversion);
  345.     if (hp->h_from)        
  346.         free(hp->h_from);
  347.     if (hp->h_date)        
  348.         free(hp->h_date);
  349.     if (hp->h_newsgroups)    
  350.         free(hp->h_newsgroups);
  351.     if (hp->h_subject)    
  352.         free(hp->h_subject);
  353.     if (hp->h_messageid)    
  354.         free(hp->h_messageid);
  355.     if (hp->h_path)        
  356.         free(hp->h_path);
  357.     if (hp->h_replyto)    
  358.         free(hp->h_replyto);
  359.     if (hp->h_sender)    
  360.         free(hp->h_sender);
  361.     if (hp->h_followupto)    
  362.         free(hp->h_followupto);
  363.     if (hp->h_datereceived)    
  364.         free(hp->h_datereceived);
  365.     if (hp->h_expires)    
  366.         free(hp->h_expires);
  367.     if (hp->h_references)    
  368.         free(hp->h_references);
  369.     if (hp->h_control)    
  370.         free(hp->h_control);
  371.     if (hp->h_distribution)    
  372.         free(hp->h_distribution);
  373.     if (hp->h_organisation)    
  374.         free(hp->h_organisation);
  375.     if (hp->h_lines)        
  376.         free(hp->h_lines);
  377.     if (hp->h_others)    
  378.         free(hp->h_others);
  379. }
  380.  
  381.  
  382. /*
  383.  * hfgets is like fgets, but deals with continuation lines.
  384.  * It also ensures that even if a line that is too long is
  385.  * received, the remainder of the line is thrown away
  386.  * instead of treated like a second line.
  387.  */
  388. char *
  389. hfgets(buf, len, fp)
  390. char *buf;
  391. int len;
  392. FILE *fp;
  393. {
  394.     register int c;
  395.     register char *cp, *tp;
  396.  
  397.     if ((cp = fgets(buf, len, fp)) == NIL(char))
  398.         return NIL(char);
  399.  
  400.     if (*cp == '\n')
  401.         return cp;
  402.  
  403.     tp = cp + strlen(cp);
  404.     if (tp[-1] != '\n') {
  405.         /* Line too long - part read didn't fit into a newline */
  406.         while ((c = getc(fp)) != '\n' && c != EOF)
  407.             ;
  408.     } else
  409.         *--tp = '\0';    /* clobber newline */
  410.  
  411.     while ((c = getc(fp)) == ' ' || c == '\t') {
  412.         /* Continuation line. */
  413.         while ((c = getc(fp)) == ' ' || c == '\t')
  414.             ;
  415.         if (tp - cp < len) {
  416.             *tp++ = ' ';
  417.             *tp++ = c;
  418.         }
  419.         while ((c = getc(fp)) != '\n' && c != EOF)
  420.             if (tp - cp < len)
  421.                 *tp++ = c;
  422.     }
  423.     *tp++ = '\n';
  424.     *tp++ = '\0';
  425.     if (c != EOF)
  426.         ungetc(c, fp);    /* push back first char of next header */
  427.     return cp;
  428. }
  429.  
  430.  
  431. /*
  432.  * time to ascii
  433.  *    leave time in static var
  434.  */
  435. char *
  436. ttoa(t)
  437. long t;
  438. {
  439.     static char buf[40];
  440.     struct tm *tp;
  441.     extern struct tm *localtime();
  442.  
  443.     tp = localtime(&t);
  444.     sprintf(buf, "%s, %d %s %d %02d:%02d:%02d %s", weekdays[tp->tm_wday],
  445.          tp->tm_mday, months[tp->tm_mon], tp->tm_year, tp->tm_hour, tp->tm_min,
  446.          tp->tm_sec, tzone);
  447.     return buf;
  448.  
  449. }
  450.  
  451.  
  452. /*
  453.  * ascii to time
  454.  * return 0L on error
  455.  */
  456. long
  457. atot(s)
  458. char *s;
  459. {
  460.     char *argv[4];
  461.     int day, year, hour, min, sec;
  462.     char month[10], sday[10], stime[10], syear[10];
  463.     extern long maketime();
  464.  
  465.     if (sscanf(s, "%*s %d %*[ -] %9[^ -] %*[ -] %d %2d:%2d:%2d", &day, month,
  466.          &year, &hour, &min, &sec) != 6)
  467.         return 0L;
  468.     sprintf(sday, "%d", day);
  469.     sprintf(stime, "%d:%d:%d", hour, min, sec);
  470.     sprintf(syear, "%d", 1900 + year);
  471.     argv[0] = sday;
  472.     argv[1] = month;
  473.     argv[2] = stime;
  474.     argv[3] = syear;
  475.     return maketime(4, argv, STIMES);
  476. }
  477.  
  478.  
  479.